home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_100
/
173_01
/
lex.y
< prev
next >
Wrap
Text File
|
1980-01-01
|
18KB
|
748 lines
/*
HEADER: CUG nnn.nn;
TITLE: LEX - A Lexical Analyser Generator
VERSION: 1.1 for IBM-PC
DATE: Jan 30, 1985
DESCRIPTION: A Lexical Analyser Generator. From UNIX
KEYWORDS: Lexical Analyser Generator YACC C PREP
SYSTEM: IBM-PC and Compatiables
FILENAME: LEX.Y
WARNINGS: This program is not for the casual user. It will
be useful primarily to expert developers.
This file must be processed by YACC with the -d
option.
CRC: N/A
SEE-ALSO: YACC and PREP
AUTHORS: Charles H. Forsyth
Scott Guthery 11100 leafwood lane Austin, TX 78750
Andrew M. Ward, Jr. Houston, Texas (Modifications)
COMPILERS: LATTICE C
REFERENCES: UNIX Systems Manuals -- Lex Manual on distribution disks
*/
/*
* Copyright (c) 1978 Charles H. Forsyth
*
*
* Modified 22-Jun-86 Andrew Ward -- Modified code to compile under Lattice C
* version 3.0h. Corrected several errors
* from the assumption that pointers and
* integers are the same size.
* New debug code for LATTICE C using assert
* to test for wild pointers. Using a proper
* YACC this will produce a ytab.c file that
* does not need hand modification.
*/
/*
* lex -- grammar/lexical analyser
*/
%{
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "lexlex.h"
char ccl[ (NCHARS+1) / NBPC ];
int sz_ccl = (NCHARS+1) / NBPC;
char *yysterm[] = {
"error",
"NAME",
"CCLASS",
"STRING",
"CONCAT",
0 };
extern char *progname;
extern char *breakc;
extern char *ignore;
extern char *illeg;
extern int nlook;
char *lalloc();
struct des {
struct nfa *d_start;
struct nfa *d_final;
};
struct nlist {
struct nlist *nl_next;
struct nfa *nl_base;
struct nfa *nl_end;
struct nfa *nl_start;
struct nfa *nl_final;
char *nl_name;
}
*nlist;
extern int str_len;
extern struct nfa *nfap;
extern struct nfa *elem(int, char *);
extern struct des *newdp(struct nfa *, struct nfa *);
extern struct nlist *lookup(char *);
extern int mapc(int);
extern int cclass(void);
extern void name(int);
extern void action(void);
extern void skipstr(int);
extern void copycode(void);
extern void string(int);
extern void copynfa(struct nlist *, struct nfa *, struct des *);
extern void spccl(char *, char *, struct des *, char **);
extern void unget( int );
extern void copy(char *, char *, int);
extern void errmsg(char *);
extern void yyerror(char *, char *);
extern void newcase(int);
extern void llactr(void);
extern void setline(void);
extern void cclprint(char *);
extern int yyline;
%}
%union {
char *buff;
struct nlist *list;
struct des *des_ptr;
struct nfa *elem_ptr;
}
%term NAME CCLASS STRING CONCAT
%token <buff> STRING NAME CCLASS
%type <buff> NAME CCLASS
%type <list> namedef name
%type <des_ptr> pattern regexp
%left ';'
%left '='
%left '/'
%left '|'
%left '(' NAME STRING CCLASS
%left CONCAT
%left '*'
%%
%{
struct nfa *np, *nbase;
char *cp;
struct des *dp, *dp1;
struct trans *tp;
struct nlist *nl;
int i, c;
%}
lexfile:
auxiliary_section translation_section
|
;
auxiliary_section:
auxiliaries '%' '%'
| '%' '%'
;
auxiliaries:
auxiliaries auxiliary
| auxiliary
;
auxiliary:
namedef '=' regexp ';' ={
dp = $3;
nl = $1;
np = nl->nl_base;
nl->nl_start = dp->d_start;
nl->nl_final = dp->d_final;
nl->nl_end = nfap;
#ifdef DEBUG
printf("NFA for %s\n", nl->nl_name);
nfaprint(dp->d_start, nl->nl_base);
#endif
i = nl->nl_end - nl->nl_base;
nbase = (struct nfa *)lalloc(i, sizeof(struct nfa), "nfa storage");
copynfa(nl, nbase, dp);
nl->nl_start = dp->d_start;
nl->nl_final = dp->d_final;
nl->nl_end = nbase+i;
nl->nl_base = nbase;
nfap = np;
spccl(nl->nl_name, "ignore", dp, &ignore);
spccl(nl->nl_name, "break", dp, &breakc);
spccl(nl->nl_name, "illegal", dp, &illeg);
}
| '%' '{' ={
copycode();
}
;
namedef:
NAME ={
$$ = lookup($1);
$$->nl_base = nfap;
if ($$->nl_start)
yyerror("%s redefined", $$->nl_name);
}
;
name:
NAME = {
$$ = lookup($1);
}
;
regexp:
CCLASS = {
np = elem(CCL, $1);
$$ = newdp(np, (np->n_succ[0] = elem(FIN, (char *)NULL ) ) );
}
| STRING ={
cp = $1;
if (str_len == 0) {
np = elem(EPSILON, (char *)NULL );
$$ = newdp(np, (np->n_succ[0] = elem(FIN, (char *)NULL ) ) );
/* return(0);*/ /* AMW: the return here appears in error */
}
else /* AMW: else stmt added 1 May 1986 $$->d_start added */
{
$$->d_start = np = elem(*cp++, (char *)NULL);
while(--str_len > 0)
np = np->n_succ[0] = elem(*cp++,(char *)NULL);
$$ = newdp($$->d_start, ( np->n_succ[0] = elem( FIN, (char *)NULL ) ) );
}
}
| name ={
if ((nl = $1)->nl_end == NULL)
{
yyerror("%s not defined", nl->nl_name);
nl->nl_base = nl->nl_end = elem(FIN, (char *)NULL);
nl->nl_start = nl->nl_final = nl->nl_base;
}
$$ = dp = (struct des *)lalloc(1, sizeof(struct des), "dfa input");
nbase = nfap;
i = nl->nl_end - nl->nl_base;
if ((nfap += i) >= &nfa[MAXNFA]) {
errmsg("Out of NFA nodes");
exit(1);
}
copynfa(nl, nbase, dp);
}
| regexp '*' ={
$$ = dp = $1;
dp->d_start = newnfa(EPSILON, (np = dp->d_start), (struct nfa *)NULL);
dp->d_final->n_char = EPSILON;
dp->d_final->n_succ[0] = np;
dp->d_final->n_succ[1] = np = elem(FIN, (char *)NULL);
dp->d_start->n_succ[1] = np;
dp->d_final = np;
}
| regexp '|' regexp ={
$$ = dp = $1;
dp->d_start = newnfa(EPSILON, dp->d_start, $3->d_start);
dp->d_final->n_char = EPSILON;
dp->d_final = dp->d_final->n_succ[0] = np = elem(FIN, (char *)NULL );
dp = $3;
dp->d_final->n_char = EPSILON;
dp->d_final->n_succ[0] = np;
#ifdef DEBUG
assert( isdata( (char *)$3, sizeof( struct des) ) );
#endif
free((char *)$3);
}
| regexp regexp %prec CONCAT ={
$$ = $1;
dp = $2;
np = $$->d_final;
$$->d_final = dp->d_final;
np->n_char = dp->d_start->n_char;
np->n_ccl = dp->d_start->n_ccl;
np->n_succ[0] = dp->d_start->n_succ[0];
np->n_succ[1] = dp->d_start->n_succ[1];
#ifdef DEBUG
assert( isdata( (char *)$2, sizeof( struct nlist) ) );
#endif
free((char *)$2);
}
| '(' regexp ')' ={
$$ = $2;
}
;
translation_section:
translations ={
ending();
trans1:
printf("\nNFA for complete syntax\n");
printf("state 0\n");
for (tp = trans; tp < transp; tp++)
printf("\tepsilon\t%d\n", tp->t_start-nfa);
for (tp = trans; tp < transp; tp++)
nfaprint(tp->t_start, nfa);
;
}
| ={
goto trans1;
}
;
translations:
translations translation
| llactr translation
;
llactr:
={
llactr();
}
;
translation:
pattern action ={
dp = $1;
newtrans(dp->d_start, dp->d_